package org.nuplay;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.Mixer.Info;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;



public class NuPlayAudioClient extends JFrame implements ActionListener, WindowListener, LineListener, ChangeListener {
	

	private JComboBox audio_devices_choose;
	private JTextField ip_number_choose;
	private JComboBox channel;
	private JProgressBar sound_level_indicator;
	private JSlider treshold_control;
	
	private JButton connect_button;
	private NuPlayAudioSend audio_send;
	private boolean connected;
	
	public NuPlayAudioClient() {
		connected = false;
		build_ui();
		init_audio_devices();
	}

	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource() == connect_button) {
			if (connected) {
				disconnect();
			} else {
				connect();
			}
		}
	}
	
	private void build_ui() {
		addWindowListener(this);
		getContentPane().setLayout( new BorderLayout() );

		
		
		
		JPanel topPanel = new JPanel();
		topPanel.setLayout( null );
		getContentPane().add( topPanel, BorderLayout.CENTER );
		
		JLabel label_audio_device = new JLabel("Which AUDIO-in device to use?");
		label_audio_device.setBounds(20, 20, 200, 20);
		audio_devices_choose = new JComboBox();
		audio_devices_choose.setBounds( 20, 40, 260, 20 );
		topPanel.add(label_audio_device);
		topPanel.add(audio_devices_choose);
	
		JLabel label_ip_address = new JLabel("Where is NuPlay running at?");
		label_ip_address.setBounds(20,70, 200, 20);
		
		ip_number_choose = new JTextField();
		ip_number_choose.setBounds( 20, 90, 260, 20 );
		try {
			ip_number_choose.setText(InetAddress.getLocalHost().getHostAddress());
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		
		topPanel.add(label_ip_address);
		topPanel.add(ip_number_choose);
		
		
		JLabel channel_text = new JLabel("Which channel to use?");
		channel_text.setBounds(20,120, 200, 20);
	
		
		channel = new JComboBox();
		for(int i=0; i < 32;i++) {
			channel.addItem(new Integer(i + 1));
		}
		
		channel.setBounds( 20, 140, 260, 20 );
		topPanel.add(channel_text);
		topPanel.add(channel);
		
	
		
		JLabel threshold_text = new JLabel("Change audio threshold:");
		threshold_text.setBounds(20,170, 200, 20);
		topPanel.add(threshold_text);
		
		sound_level_indicator = new JProgressBar();
		sound_level_indicator.setMaximum(100);
		sound_level_indicator.setMinimum(0);
		sound_level_indicator.setValue(0);
		
		
		
		treshold_control = new JSlider(JSlider.HORIZONTAL, 0, 100, 50);
		treshold_control.setMajorTickSpacing(20);
		treshold_control.setMinorTickSpacing(5);
		treshold_control.setPaintTicks(true);
		treshold_control.setPaintLabels(true);
		treshold_control.addChangeListener(this);
		
		sound_level_indicator.setBounds( 30, 200, 240, 10 );
		sound_level_indicator.setForeground(new Color(255,0,0));
		treshold_control.setBounds( 20, 210, 260, 50 );
		topPanel.add(sound_level_indicator);
		topPanel.add(treshold_control);
		
		connect_button = new JButton("Connect to NuPlay.");
		connect_button.addActionListener(this);
		connect_button.setBounds( 20, 280, 200, 20 );
		topPanel.add(connect_button);

		java.net.URL imageURL = NuPlayAudioClient.class.getResource("nuplay.png");
		if (imageURL != null) {
			ImageIcon icon = new ImageIcon(imageURL);
			JLabel image_label = new JLabel(icon);
			this.setIconImage(icon.getImage());
			image_label.setBounds( 240, 270, 50, 77 );
			topPanel.add(image_label);
		}
	}
	
	public void update(LineEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("event" + arg0.getType());
	}
	
	private void init_audio_devices() {
		try {
			
			Info[] audio_devices = AudioSystem.getMixerInfo();
			
				for(int i = 0; i < audio_devices.length; i++) {
						Mixer mixer = AudioSystem.getMixer(audio_devices[i]);
						AudioFormat format = new AudioFormat(22000,8,1,true, true);
						DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
						
						boolean line_supported = mixer.isLineSupported(info);
						if (line_supported) {
							TargetDataLine line = (TargetDataLine)mixer.getLine(info);
							audio_devices_choose.addItem(mixer.getMixerInfo().getName());
						}
				}
	} catch (Exception e) {
		e.printStackTrace();
	} 
	if (audio_devices_choose.getItemCount() == 0) {
		connect_button.setEnabled(false);
	}
	}
	
	private void close_audio_device() {
	}
	
	private void open_audio_device() {
		try {
			Info[] audio_devices = AudioSystem.getMixerInfo();
				for(int i = 0; i < audio_devices.length; i++) {
						Mixer mixer = AudioSystem.getMixer(audio_devices[i]);
						AudioFormat format = new AudioFormat(22000,8,1,true, true);
						DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
						boolean line_supported = mixer.isLineSupported(info);
						if (line_supported) {
							TargetDataLine line = (TargetDataLine)mixer.getLine(info);
							if (mixer.getMixerInfo().getName().equals(audio_devices_choose.getSelectedItem())) {
								
								audio_send = new NuPlayAudioSend(line, format,treshold_control.getValue() ,(Integer)channel.getSelectedItem(),InetAddress.getByName(ip_number_choose.getText()) ,sound_level_indicator);
								break;
							}
							
						}
				}
	} catch (Exception e) {
		e.printStackTrace();
	}
	}
	
	
	private void disconnect() {
		connected = false;
		if (audio_send != null) {
			audio_send.close();
			audio_send = null;
		}
		connect_button.setText("Connect to NuPlay.");
		close_audio_device();
	}
	
	private void connect() {
		connected = true;
		connect_button.setText("Disconnect from NuPlay.");
		open_audio_device();
	}
	
	public void close() {
		System.exit(0);
	}

	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame main_window = new NuPlayAudioClient();
		main_window.setSize(320, 375);
		main_window.setTitle("NuPlay AUDIO client V1.0");
		main_window.setVisible(true);
	}

	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void windowClosing(WindowEvent e) {
		close();
		
	}

	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void stateChanged(ChangeEvent e) {
		// TODO Auto-generated method stub
		if (audio_send != null) {
			audio_send.setLevel(treshold_control.getValue());
		}
	}


	
}
